/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction;

import org.springframework.lang.Nullable;

import java.sql.Connection;

/**
 * Interface that defines Spring-compliant transaction properties.
 * Based on the propagation behavior definitions analogous to EJB CMT attributes.
 *
 * <p>Note that isolation level and timeout settings will not get applied unless
 * an actual new transaction gets started. As only {@link #PROPAGATION_REQUIRED},
 * {@link #PROPAGATION_REQUIRES_NEW} and {@link #PROPAGATION_NESTED} can cause
 * that, it usually doesn't make sense to specify those settings in other cases.
 * Furthermore, be aware that not all transaction managers will support those
 * advanced features and thus might throw corresponding exceptions when given
 * non-default values.
 *
 * <p>The {@link #isReadOnly() read-only flag} applies to any transaction context,
 * whether backed by an actual resource transaction or operating non-transactionally
 * at the resource level. In the latter case, the flag will only apply to managed
 * resources within the application, such as a Hibernate {@code Session}.
 *
 * @author Juergen Hoeller
 * @since 08.05.2003
 * @see PlatformTransactionManager#getTransaction(TransactionDefinition)
 * @see org.springframework.transaction.support.DefaultTransactionDefinition
 * @see org.springframework.transaction.interceptor.TransactionAttribute
 */
public interface TransactionDefinition {

	// require：如果当前没有事务，就新建一个事务，如果已存在一个事务中，加入到这个事务中，这是最常见的选择,也是默认的
	int PROPAGATION_REQUIRED = 0;

	// supports：支持当前事务，如果没有当前事务，就以非事务方法执行。
	int PROPAGATION_SUPPORTS = 1;

	// mandatory：使用当前事务，如果没有当前事务，就抛出异常。
	int PROPAGATION_MANDATORY = 2;

	// require_new：新建事务，如果当前存在事务，把当前事务挂起。
	int PROPAGATION_REQUIRES_NEW = 3;

	// not_supported：以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。
	int PROPAGATION_NOT_SUPPORTED = 4;

	// never：以非事务方式执行操作，如果当前事务存在则抛出异常。
	int PROPAGATION_NEVER = 5;

	// nested：嵌套的，如果当前存在事务，则在嵌套事务内执行，如果没有事务就新建一个事务。
	int PROPAGATION_NESTED = 6;


	/**
	 * 使用基础数据存储的默认隔离级别。所有其他级别都对应于 JDBC 隔离级别。
	 * @see java.sql.Connection
	 */
	int ISOLATION_DEFAULT = -1;

	// read_uncommitted：读未提交
	int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;//1

	// read_committed：读已提交
	int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;//2

	// repeatable_read：可重复读
	int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;//4

	// serializable：串行化
	int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;//8

	/**
	 * 使用基础事务系统的默认超时，如果不支持超时，则不使用超时。
	 */
	int TIMEOUT_DEFAULT = -1;


	// 返回定义的事务传播行为
	int getPropagationBehavior();

	// 返回定义的事务隔离级别
	int getIsolationLevel();

	// 返回定义的事务超时时间
	int getTimeout();

	// 返回定义的事务是否是只读的
	boolean isReadOnly();

	// 返回定义的事务名字
	@Nullable
	String getName();

}
